#!/usr/bin/env python

import os
import model
import component
import sqlalchemy as sa

import sqlalchemy.orm as sao
import dateutil.parser

from datetime import datetime
from model import DeclarativeBase

__all__ = ['Search']

class Search(DeclarativeBase):
    """Search Class
    
    Attributes:
        id: An integer indicating the primary key.
        hostId: An integer for host foreign key.
        tagId: An integer for tag foreign key.
    """
    
    __tablename__ = 'searchs'
    
    id = sa.Column(sa.Integer, primary_key=True)
    hostId = sa.Column(sa.Integer, sa.ForeignKey("hosts.id"), nullable=False,
                       index=True)
    tagId = sa.Column(sa.Integer, sa.ForeignKey("tags.id"), nullable=False,
                      index=True)
    createdAt = sa.Column(sa.DateTime, default=datetime.now)
    updatedAt = sa.Column(sa.DateTime, default=datetime.now,
                          onupdate=datetime.now)
    
    host = sao.relationship('Host', uselist=False)
    tag = sao.relationship('Tag', uselist=False)
    
    def download(self, page):
        """Download post data from host.
        
        Args:
            page: An integer indicating the page to download. Start from 1.
            
        Returns:
            A tuple of response header and collection of Namespace instance
            representing post data.
            
            Namespace Attributes:
                id: An integer indicating the post id.
                hostId: An integer indicating host id.
                tagId: An integer indicating tag id.
                tags: A set containing all tags for post.
                md5: An MD5 hash that uniquely identifies the image.
                url: A url where the image located.
                size: An integer of image size.
                extension: A string explaining the image type.
                createdAt: A datetime when the post created.
        """
        
        if self.host.type == model.Host.TYPE_GELBOORU:
            data = self.downloadXml(page)
        else:
            data = self.downloadJson(page)
        return data
    
    def downloadJson(self, page):
        """Download post data from host in JSON format.
        
        Args:
            page: An integer indicating the page to download. Start from 1.
            
        Returns:
            A tuple of response header and collection of Namespace instance
            representing post data.
            
            Namespace Attributes:
                id: An integer indicating the post id.
                hostId: An integer indicating host id.
                tagId: An integer indicating tag id.
                tags: A set containing all tags for post.
                md5: An MD5 hash that uniquely identifies the image.
                url: A url where the image located.
                size: An integer of image size.
                extension: A string explaining the image type.
                createdAt: A datetime when the post created.
        """
        
        url = self.host.createUrl(page, self.tag.name)
        header, body = self.getJson(url)
        data = []
        if header['status'] == 200:
            for post in body:
                datum = component.Namespace()
                datum.id = post['id']
                datum.hostId = self.hostId
                datum.tagId = self.tagId
                datum.md5 = post['md5']
                datum.url = post['file_url']
                datum.size = post['file_size']
                
                if self.host.type == model.Host.TYPE_DANBOORU:
                    key = 'tag_string'
                else:
                    key = 'tags'
                tags = [x.strip() for x in post[key].strip().split(' ')]
                datum.tags = set(tags) - set([''])
                
                fileName = post['file_url'].split('/')[-1]
                datum.extension = os.path.splitext(fileName)[1][1:].lower()
                
                try:
                    createdAt = datetime.fromtimestamp(post['created_at'])
                except:
                    createdAt = dateutil.parser.parse(post['created_at'])
                    
                datum.createdAt = createdAt
                data.append(datum)
                
        return (header, data)
    
    def downloadXml(self, page):
        """Download post data from host in XML format.
        
        Args:
            page: An integer indicating the page to download. Start from 1.
            
        Returns:
            A tuple of response header and collection of Namespace instance
            representing post data.
            
            Namespace Attributes:
                id: An integer indicating the post id.
                hostId: An integer indicating host id.
                tagId: An integer indicating tag id.
                tags: A set containing all tags for post.
                md5: An MD5 hash that uniquely identifies the image.
                url: A url where the image located.
                size: An integer of image size.
                extension: A string explaining the image type.
                createdAt: A datetime when the post created.
        """
        
        url = self.host.createUrl(page, self.tag.name)
        return url
    